[clickable]
	Clickable Version 1.0b5 -- Created by Johan Slve johan@solve.se
	This macro makes URLs in a text clickable. It works with "http://", "ftp://",
	addresses beginning with " www." and with email addresses (anything 
	containing "@"). 
	The output is encoded for extended characters but does not support 
	preserving linebreaks. Use EncodeNone for the input. 
	
	Usage examples: 
		[clickable: 'This is a clickable link to http://www.blueworld.com. My 
		email address is johan@solve.se']
		[clickable: (var: 'text', EncodeNone)]

	
#MACRO_BEGIN
[Lasso_Comment]
<!-- Lasso_comment turns off any text output so we can comment freely without 
cluttering the resulting source code -->

[Macro_Parent: #MACRO_INSERT_PARAMS#]
[Variable_Set: 'macro_clickable_text'=(macro_param: '1', EncodeNone)]
[/Macro_Parent]

<!-- All variable names in this macro begin with "macro_clickable_" 
to reduce the risk of conflicts with other variables --> 

<!-- Loop once for each "protocol" we handle 
To add a protocol, just increase the loop count and add the match string 
for the protocol. The email protocol is handled in a special way so you can
write just an email address in the text without needing to preceed it
with "mailto:". -->
[loop: '4']
	[if: (loopcount)=='1']
		[var_set: 'macro_clickable_protocol'='http://']
	[else: if: (loopcount)=='2']
		[var_set: 'macro_clickable_protocol'='ftp://']
	[else: if: (loopcount)=='3']
		[var_set: 'macro_clickable_protocol'='@']
	[else: if: (loopcount)=='4']
		[var_set: 'macro_clickable_protocol'=' www.']
	[/if]
	
	<!-- Each protocol starts looking at the beginning of the text -->
	[var_set: 'macro_clickable_start'='0']
	
	<!-- loop once for each occurence in the text of the protocol in question -->
	[loop: (math_sub: (String_CountFields: delimiter=(var: 'macro_clickable_protocol', EncodeNone), 
		(var: 'macro_clickable_text', EncodeNone)), '1')]
	
		<!-- first take care of handling url:s that end with a comma, full 
		stop (period+space) and some other separators by replacing the separators 
		with space, store the result in a separate variable that's only used to 
		find beginning and end of URLs.
		Make sure you replace with the same number of characters so the word positions
		in the resulting variable is the same as in the original text. -->
		[var_set: 'macro_clickable_text_url'=
			(string_replace: encodenone, find='. ', replace='  ',
			(string_replace: encodenone, find='>', replace=' ',
			(string_replace: encodenone, find='<', replace=' ',
			(string_replace: encodenone, find=',', replace=' ',
			(string_replace: encodenone, find='!', replace=' ',
			(string_replace: encodenone, find='\r', replace=' ',
			(String_Concatenate: EncodeNone, ' ', (var: 'macro_clickable_text', encodenone), ' ')
			))))))]
		
		<!-- find where the url starts -->
		[var_set: 'macro_clickable_start'=(String_FindPosition: 
			StartPosition=(math_add: (var: 'macro_clickable_start'), '1'), 
			Find=(var: 'macro_clickable_protocol', EncodeNone), 
			(var: 'macro_clickable_text_url', encodenone))]
		
		[if: (var: 'macro_clickable_protocol', EncodeNone)=='@']
			<!-- email addresses are handled separately.
			Work your way backwards to find the first space before @ but 
			don't go further than 100 characters backwards -->
			[loop: '100']
				[var_set: 'macro_clickable_start'=(math_sub: (var: 'macro_clickable_start'), '1')]
				[if: (String_Extract: StartPosition=(var: 'macro_clickable_start', EncodeNone), 
					EndPosition=(var: 'macro_clickable_start', EncodeNone), 
					(var: 'macro_clickable_text_url', EncodeNone))==' '||(var: 'macro_clickable_start')<'1']
					<!-- stop the loop when finding a space or reaching the beginning of the text -->
					[LoopAbort]
				[/if] 
			[/loop]
			[var_set: 'macro_clickable_start'=(math_add: (var: 'macro_clickable_start'), '1')]
			[if: (var: 'macro_clickable_start')<'1'] <!-- the text begins with an email address -->
				[var_set: 'macro_clickable_start'='1'] <!-- so the URL must start at character 1 -->
			[/if]	
		[/if]
		[if: (var: 'macro_clickable_protocol', EncodeNone)==' www.']
			<!-- Remove the leading space for links beginning with " www." -->
			[var_set: 'macro_clickable_start'=(math_add: (var: 'macro_clickable_start'), '1')]
		[/if]
		
		<!-- find where the url ends -->
		[var_set: 'macro_clickable_end'=(math_sub:
			(String_FindPosition: StartPosition=(var: 'macro_clickable_start'), Find=' ', 
			(var: 'macro_clickable_text_url', encodenone)), '1')]
			
		<!-- compensate for the added leading space in macro_clickable_text_url -->
		[var_set: 'macro_clickable_start'=(math_sub: (var: 'macro_clickable_start'), '1')]
		[var_set: 'macro_clickable_end'=(math_sub: (var: 'macro_clickable_end'), '1')]
		
		<!-- extract the url -->
		[var_set: 'macro_clickable_url'=(String_Extract: EncodeNone, 
			StartPosition=(var: 'macro_clickable_start'), 
			EndPosition=(var: 'macro_clickable_end'), 
			(var: 'macro_clickable_text', EncodeNone))]
		[If: (var: 'macro_clickable_protocol', EncodeNone)=='@'&&(String_Extract: EncodeNone, 
			StartPosition='1', EndPosition='7', 
			(var: 'macro_clickable_url', EncodeNone))!='mailto:']
			<!-- Handle email addresses separately if they don't begin with 
			"mailto:" and add the real protocol to them -->
			[var_set: 'macro_clickable_url_href'=(String_Concatenate: EncodeNone, 
				'mailto:', (var: 'macro_clickable_url', EncodeNone))]
		[else: if: (var: 'macro_clickable_protocol', EncodeNone)==' www.']
			<!-- Add http:// to addresses beginning with " www." -->
			[var_set: 'macro_clickable_url_href'=(String_Concatenate: EncodeNone, 
				'http://', (var: 'macro_clickable_url', EncodeNone))]		
		[Else]
			[var_set: 'macro_clickable_url_href'=(var: 'macro_clickable_url', EncodeNone)]
		[/If]
		
		[var_set: 'macro_clickable_linktext'=(var: 'macro_clickable_url', EncodeNone)], 

		<!-- store the result -->
		[var_set: 'macro_clickable_text'=(string_replace:encodenone, 
			find=(var: 'macro_clickable_url'), 
			replace=(string_concatenate: encodenone,
				'<a href="',
				(var: 'macro_clickable_url_href', EncodeNone), '">', 
				(var: 'macro_clickable_linktext', EncodeNone), '</a>'), 
			(var: 'macro_clickable_text', EncodeNone))]
		
		<!-- when inserting the hrefs, the text has got longer. Add the difference in length 
		to the start value to be ready for the next loop. -->
		[var_set: 'macro_clickable_start'=(math_add: (var: 'macro_clickable_start'), 
			(string_length: (var: 'macro_clickable_url_href')), 
			(string_length: (var: 'macro_clickable_linktext')), 
			(string_length: '<a href=""></a>'))]
			
	[/loop]

[/loop]

<!-- clean up the output by applying proper encoding and restore quotes so they work with URLs. -->
[var_set: 'macro_clickable_text'=(string_replace: EncodeNone, find='&#34;', replace='\"', 
	(var: 'macro_clickable_text', EncodeSmart))]

<!-- Show the output -->
[/Lasso_Comment][var: 'macro_clickable_text', EncodeNone]
#MACRO_END


